package com.spzx.cart.service.impl;

import com.spzx.cart.domain.CartInfo;
import com.spzx.cart.service.ICartService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.common.security.utils.SecurityUtils;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.api.domain.ProductSku;
import com.spzx.product.api.domain.SkuPrice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class CartServiceImpl implements ICartService {

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    RemoteProductService remoteProductService;

    @Override
    public void addToCart(Long skuId, Integer skuNum) {
        //1.准备大key
        Long userId = SecurityUtils.getUserId();
        String cartKey = getCartKey(userId);

        //2.准备小key
        String hashKey = skuId.toString();

        //3.准备CartInfo

        //3.1 判断购物车是否添加过当前商品
        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);

        if(boundHashOperations.hasKey(hashKey)){ //已添加
            CartInfo cartInfo = boundHashOperations.get(hashKey);
            Integer totalNum = cartInfo.getSkuNum()+skuNum;
            Integer threshold = 99; // 单品总数量不能超过99件
            totalNum = totalNum >  threshold ? threshold : totalNum;
            cartInfo.setSkuNum(totalNum);
            cartInfo.setUpdateTime(new Date());
            boundHashOperations.put(hashKey,cartInfo);
        }else{ //没有添加过，首次添加
            CartInfo cartInfo = new CartInfo();
            cartInfo.setUserId(userId);
            cartInfo.setSkuId(skuId);

            Long size = boundHashOperations.size();

            if(++size>50){
                throw new ServiceException("超过上限50个!"); //添加不同商品上限50个。
            }

            R<ProductSku> productSkuResult = remoteProductService.getProductSku(skuId, SecurityConstants.INNER);
            if(R.FAIL == productSkuResult.getCode()){
                throw new ServiceException(productSkuResult.getMsg());
            }
            ProductSku productSku = productSkuResult.getData();
            cartInfo.setCartPrice(productSku.getSalePrice());
            cartInfo.setSkuPrice(productSku.getSalePrice());
            cartInfo.setSkuNum(skuNum);
            cartInfo.setThumbImg(productSku.getThumbImg());
            cartInfo.setSkuName(productSku.getSkuName());
            cartInfo.setCreateTime(new Date());
            cartInfo.setUpdateTime(new Date());
            boundHashOperations.put(hashKey,cartInfo);
        }
    }

    /**
     * 构建“用户”购物车hash结构key
     * @param userId
     * @return
     */
    private String getCartKey(Long userId) {
        return "user:cart:" + userId;
    }


    @Override
    public List<CartInfo> getCartList() {
        //1.准备大key
        Long userId = SecurityUtils.getUserId();
        String cartKey = getCartKey(userId);

        //2.获取购物车里所有商品列表
        List<CartInfo> cartInfoList = redisTemplate.opsForHash().values(cartKey);
        if(CollectionUtils.isEmpty(cartInfoList)){
            return new ArrayList<>();
        }

        //2.1 按照添加时间倒序排序
        List<CartInfo> cartInfoSortList = cartInfoList.stream().sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime())).collect(Collectors.toList());

        //2.2 更新购物车中商品最新价格
        //2.2.1 首先获取skuId集合 ： List<Long>

        List<Long> skuIdList3 = cartInfoSortList.stream().map(CartInfo::getSkuId).toList();
//        System.out.println("skuIdList3 = " + skuIdList3);
//        Set<Long> skuIdList = redisTemplate.opsForHash().keys(cartKey);
//        System.out.println("skuIdList = " + skuIdList);
//        List<Long> skuIdList2 = new ArrayList<>(skuIdList); //集合里skuId为String类型，并不是泛型Long
//        System.out.println("skuIdList2 = " + skuIdList2);
        //报类型转换错误
//        R<List<SkuPrice>> skuPriceListResult = remoteProductService.getSkuPriceList(new ArrayList<>(skuIdList2), SecurityConstants.INNER);

        //2.2.2 根据skuId集合获取他们的List<SkuPrice>
        R<List<SkuPrice>> skuPriceListResult = remoteProductService.getSkuPriceList(skuIdList3, SecurityConstants.INNER);
        if(R.FAIL == skuPriceListResult.getCode()){
            throw new ServiceException(skuPriceListResult.getMsg());
        }
        List<SkuPrice> skuPriceList = skuPriceListResult.getData();
        Map<Long, BigDecimal> skuIdToSalePriceMap = skuPriceList.stream().collect(Collectors.toMap(SkuPrice::getSkuId, SkuPrice::getSalePrice));
        //2.2.3 更新购物车中价格
        for (CartInfo cartInfo : cartInfoSortList) {
            cartInfo.setSkuPrice(skuIdToSalePriceMap.get(cartInfo.getSkuId()));
        }

        return cartInfoSortList;
    }


    @Override
    public void deleteCart(Long skuId) {
        //1.准备大key
        Long userId = SecurityUtils.getUserId();
        String cartKey = getCartKey(userId);

        //2.准备小key
        String hashKey = skuId.toString();

        //3.只删除购物车当前商品
        redisTemplate.opsForHash().delete(cartKey,hashKey);
    }

    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        //1.准备大key
        Long userId = SecurityUtils.getUserId();
        String cartKey = getCartKey(userId);

        //2.准备小key
        String hashKey = skuId.toString();

        //3.只修改当前商品勾选状态
        BoundHashOperations<String,String,CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        CartInfo cartInfo = hashOps.get(hashKey);
        cartInfo.setIsChecked(isChecked);
        hashOps.put(hashKey,cartInfo);
    }

    @Override
    public void allCheckCart(Integer isChecked) {
        //1.准备大key
        Long userId = SecurityUtils.getUserId();
        String cartKey = getCartKey(userId);

        //2.设置所有的商品勾选状态为当前状态
        BoundHashOperations<String,String,CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOps.values();
        for (CartInfo cartInfo : cartInfoList) {
            cartInfo.setIsChecked(isChecked);
            hashOps.put(cartInfo.getSkuId().toString(),cartInfo);
        }
    }


    @Override
    public void clearCart() {
        //1.准备大key
        Long userId = SecurityUtils.getUserId();
        String cartKey = getCartKey(userId);

        //2.删除该用户购物车数据
        redisTemplate.delete(cartKey);
    }

    @Override
    public List<CartInfo> getCartCheckedList(Long userId) {
        //1.准备大key
        String cartKey = getCartKey(userId);

        //2.获取所有打钩的商品集合：List<CartInfo>
        List<CartInfo> cartInfoList = redisTemplate.opsForHash().values(cartKey);

        List<CartInfo> checkedCartInfoList = new ArrayList<>();
        for (CartInfo cartInfo : cartInfoList) {
            if(cartInfo.getIsChecked().intValue() == 1){
                checkedCartInfoList.add(cartInfo);
            }
        }

        return checkedCartInfoList;
    }


    @Override
    public Boolean updateCartPrice(Long userId) {
        //1.准备大key
        String cartKey = getCartKey(userId);

        BoundHashOperations<String,String,CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOps.values();

        for (CartInfo cartInfo : cartInfoList) {
            R<SkuPrice> skuPriceResult = remoteProductService.getSkuPrice(cartInfo.getSkuId(), SecurityConstants.INNER);
            if(R.FAIL == skuPriceResult.getCode()){
                throw new ServiceException(skuPriceResult.getMsg());
            }
            if(cartInfo.getIsChecked().intValue() == 1){
                SkuPrice skuPrice = skuPriceResult.getData();
                cartInfo.setCartPrice(skuPrice.getSalePrice());   //购物车商品价格问题？   cartPrice更新成最新skuPrice
                cartInfo.setSkuPrice(skuPrice.getSalePrice());
                hashOps.put(cartInfo.getSkuId().toString(),cartInfo);
            }
        }

        return true;
    }


    @Override
    public Boolean deleteCartCheckedList(Long userId) {
        //1.准备大key
        String cartKey = getCartKey(userId);

        BoundHashOperations<String,String,CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOps.values();
        if(!CollectionUtils.isEmpty(cartInfoList)){
            for (CartInfo cartInfo : cartInfoList) {
                if(cartInfo.getIsChecked().intValue() == 1){
                    hashOps.delete(cartInfo.getSkuId().toString());
                }
            }
        }
        return true;
    }
}
